package com.bonjour.common.view;

import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Sets;
import com.bonjour.common.helper.BytesHelper;
import com.bonjour.common.helper.StringHelper;
import com.bonjour.common.helper.ThreadFactoryHelper;
import com.bonjour.common.support.IConstant;
import com.bonjour.common.support.OperationLog;
import com.bonjour.common.view.parser.RequestSession;

import javafx.util.Pair;

final class RequestResponseLogger {
    private static final Logger OUT = LoggerFactory.getLogger(OperationLog.class);
    private static final ExecutorService LOG_EXECUTOR = Executors.newSingleThreadExecutor(ThreadFactoryHelper.threadFactoryOf("operation-log"));

    private static Set<String> FILE_RESPONSE_TYPE = Sets.newHashSet(MediaType.IMAGE_GIF_VALUE,
                                                                    MediaType.IMAGE_JPEG_VALUE,
                                                                    MediaType.IMAGE_PNG_VALUE,
                                                                    MediaType.APPLICATION_PDF_VALUE,
                                                                    MediaType.APPLICATION_OCTET_STREAM_VALUE);

    private final boolean isSR;
    private final RequestSession session;
    private final Pair<String, byte[]> result;

    RequestResponseLogger(boolean isSR, RequestSession session, Pair<String, byte[]> result) {
        this.isSR = isSR; this.session = session; this.result = result;
    }

    void submit() {
        // 静态资源请求 + 没有名字的mapping + SpringCloudEndpoint 不记录日志
        if (isSR || StringHelper.isBlank(session.operate) || IConstant.isSpringCloudEndpoint(session.uri)) {return;}
        LOG_EXECUTOR.submit(()-> {
            // 非文件
            if (!FILE_RESPONSE_TYPE.contains(result.getKey())) {
                String json = BytesHelper.string(result.getValue());
                if (MediaType.APPLICATION_JSON_UTF8_VALUE.startsWith(result.getKey())) {
                    if (json.startsWith("[") && json.startsWith("]")) {
                        OUT.info("{}", JSON.toJSONString(OperationLog.newborn(session, JSON.parseArray(json))));
                    } else {
                        OUT.info("{}", JSON.toJSONString(OperationLog.newborn(session, JSON.parseObject(json))));
                    }
                } else {
                    OUT.info("{}", JSON.toJSONString(OperationLog.newborn(session, json)));
                }
            } else {
                OUT.info("{}", JSON.toJSONString(OperationLog.newborn(session, ("文件类型：" + result.getKey()))));
            }
        });
    }
}
